from client import es_client
from client.redis_client import r
from model.wristband_models import HealthData
from service.battery import get_intensity_redis
from utils.data_operation_util import deduplicate_dict_list
from utils.logger_util import logger
from utils.date_utils import timestamp_to_str_000z
from dao.base_dao import BaseESDAO, HealthDataProcessor
from typing import Dict, List



class HealthLogDAO(BaseESDAO):
    """
    优化的健康日志DAO，使用基础DAO类和标准化处理逻辑
    """
    
    def __init__(self):
        super().__init__('p_health_logs')
    
    def _build_health_metrics(self, health_data: HealthData, data_authority: dict, 
                            intensity_dict: dict) -> List[Dict]:
        """构建健康指标数据，使用标准化处理逻辑"""
        create_date = timestamp_to_str_000z(health_data.timestamp)
        base_data = {
            'createDate': create_date,
            'imei': health_data.device_id,
            'intensity': intensity_dict['intensity'],
            'step_8_min': intensity_dict['step'],
            'dataAuthority': data_authority
        }
        
        health_metrics = []
        
        # 血压数据
        if health_data.blood_pressure_high > 0:
            bp_data = {
                **base_data,
                'dataType': '血压',
                'bloodPressureHigh': health_data.blood_pressure_high,
                'bloodPressureLow': health_data.blood_pressure_low
            }
            bp_data['exception_level'] = self._calculate_bp_exception_level(
                health_data.blood_pressure_high, 
                health_data.blood_pressure_low
            )
            health_metrics.append(bp_data)
        
        # 心率数据
        if health_data.heart_rate > 0:
            hr_data = {
                **base_data,
                'dataType': '心率',
                'healthValue': health_data.heart_rate
            }
            hr_data['exception_level'] = self._calculate_hr_exception_level(
                health_data.heart_rate, 
                intensity_dict['intensity']
            )
            health_metrics.append(hr_data)
        
        # 血氧数据
        if health_data.blood_oxygen > 0:
            bo_data = {
                **base_data,
                'dataType': '血氧',
                'healthValue': health_data.blood_oxygen
            }
            bo_data['exception_level'] = self._calculate_bo_exception_level(health_data.blood_oxygen)
            health_metrics.append(bo_data)
        
        # 体温数据
        if health_data.body_temperature > 0:
            bt_data = {
                **base_data,
                'dataType': '体温',
                'healthValue': float(health_data.body_temperature)
            }
            bt_data['exception_level'] = self._calculate_bt_exception_level(
                float(health_data.body_temperature)
            )
            health_metrics.append(bt_data)
        
        return health_metrics
    
    def _calculate_bp_exception_level(self, systolic: int, diastolic: int) -> int:
        """计算血压异常等级"""
        if systolic >= 180 or diastolic >= 120:
            return 3
        elif systolic >= 160 or diastolic >= 100:
            return 2
        elif systolic >= 140 or diastolic >= 90:
            return 1
        return 0
    
    def _calculate_hr_exception_level(self, heart_rate: int, intensity: int) -> int:
        """计算心率异常等级"""
        if heart_rate < 40 or (heart_rate > 130 and intensity < 3):
            return 3
        elif (40 <= heart_rate <= 49 or 
              (111 <= heart_rate <= 130 and intensity < 2)):
            return 2
        elif 50 <= heart_rate <= 59 or 101 <= heart_rate <= 110:
            return 1
        return 0
    
    def _calculate_bo_exception_level(self, blood_oxygen: int) -> int:
        """计算血氧异常等级"""
        if blood_oxygen < 85:
            return 3
        elif 85 <= blood_oxygen <= 89:
            return 2
        elif 90 <= blood_oxygen <= 94:
            return 1
        return 0
    
    def _calculate_bt_exception_level(self, body_temperature: float) -> int:
        """计算体温异常等级"""
        if body_temperature > 40 or body_temperature < 34:
            return 3
        elif ((37.9 <= body_temperature <= 38.5) or 
              (34 <= body_temperature <= 34.9)):
            return 2
        elif ((37.3 <= body_temperature <= 37.8) or 
              (35 <= body_temperature <= 35.5)):
            return 1
        return 0
    
    async def save_health_data(self, health_data: HealthData, data_authority: dict, 
                              intensity_dict: dict) -> Dict:
        """保存健康数据的优化版本"""
        try:
            health_metrics = self._build_health_metrics(health_data, data_authority, intensity_dict)
            
            if not health_metrics:
                return {"saved": 0, "errors": []}
            
            result = await self.bulk_index(health_metrics)
            logger.info(f'批量存入{len(health_metrics)}条健康日志数据，IMEI: {health_data.device_id}')
            return result
            
        except Exception as e:
            logger.error(f'保存健康数据失败: {e}')
            return {"saved": 0, "errors": [str(e)]}


# 向后兼容的函数
async def save_all_health(health_data: HealthData, data_authority: dict, intensity_dict: dict):
    """向后兼容的保存健康数据函数"""
    dao = HealthLogDAO()
    return await dao.save_health_data(health_data, data_authority, intensity_dict)


async def find_health_log_dao(data: dict):
    """查找健康日志数据的优化版本"""
    dao = HealthLogDAO()
    
    # 构建查询条件
    must_conditions = [
        dao.build_terms_query("imei", data['imei']),
        dao.build_time_range_query("createDate", data['startDate'], data['endDate'])
    ]
    
    # 添加数据类型过滤
    if data.get('type') and data['type'] != '':
        must_conditions.append(dao.build_term_query("dataType", data['type']))
    
    query = {
        "size": data.get('size', 1000),  # 支持自定义大小
        "query": dao.build_bool_query(must=must_conditions),
        "sort": [{"createDate": {"order": "asc"}}],
        "_source": ["imei", "createDate", "dataType", "healthValue", 
                    "bloodPressureHigh", "bloodPressureLow", "exception_level"]  # 只返回需要的字段
    }
    
    try:
        result = await dao.search_with_pagination(query)
        docs = result.get('hits', {}).get('hits', [])
        docs_sources = [hit['_source'] for hit in docs]
        
        # 去重处理
        deduplicate_list = deduplicate_dict_list(docs_sources, {'imei', 'createDate', 'dataType'})
        return deduplicate_list
        
    except Exception as e:
        logger.error(f'查询健康日志失败: {e}')
        return []


async def find_health_exception_imei(data: dict, depart: list):
    """查找健康异常IMEI的优化版本"""
    dao = HealthLogDAO()
    
    # 构建查询条件
    must_conditions = [
        dao.build_time_range_query("createDate", data['startDate'], data['endDate']),
        {"range": {"exception_level": {"gte": data['level']}}}
    ]
    
    # 添加部门过滤
    if depart[0] != 0 or len(depart) > 1:
        must_conditions.append(dao.build_terms_query("dataAuthority.depart", depart))
    
    # 构建聚合
    agg_list = data['agg_list']
    aggs = {
        "field1": {
            "terms": {
                "field": agg_list[0],
                "size": data.get('agg_size', 1000)  # 支持自定义聚合大小
            }
        }
    }
    
    if len(agg_list) > 1:
        aggs['field1']['aggs'] = {
            "field2": {
                "terms": {
                    "field": agg_list[1],
                    "size": data.get('agg_size', 1000)
                }
            }
        }
    
    query = {
        "size": 0,
        "query": dao.build_bool_query(must=must_conditions),
        "aggs": aggs
    }
    
    try:
        result = await dao.search_with_pagination(query)
        return result.get('aggregations', {}).get('field1', {}).get('buckets', [])
        
    except Exception as e:
        logger.error(f'查询健康异常IMEI失败: {e}')
        return []


async def find_health_exception_raw_data(data: dict, depart: list):
    """查找健康异常原始数据 - 专用于报告生成"""
    dao = HealthLogDAO()
    
    # 构建查询条件
    must_conditions = [
        dao.build_time_range_query("createDate", data['startDate'], data['endDate']),
        {"range":
             {"exception_level": {"gte": data['level']}}
         },
        {"range":
             {"intensity": {"lte":1}}
         }
    ]
    
    # 添加部门过滤
    if depart[0] != 0 or len(depart) > 1:
        must_conditions.append(dao.build_terms_query("dataAuthority.depart", depart))
    
    query = {
        "size": data.get('size', 10000),  # 支持大量数据查询
        "query": dao.build_bool_query(must=must_conditions),
        "sort": [{"createDate": {"order": "desc"}}],
        "_source": True  # 返回完整source数据
    }
    
    try:
        result = await dao.search_with_pagination(query)
        # 只返回_source内容的列表
        docs = result.get('hits', {}).get('hits', [])
        logger.info(f'查询健康异常原始数据成功，共{len(docs)}条记录')
        return [hit['_source'] for hit in docs]
        
    except Exception as e:
        logger.error(f'查询健康异常原始数据失败: {e}')
        return []



